package my.georings.map;

import java.util.ArrayList;

import my.georings.GeoPhoneRingsApp;
import my.georings.R;
import my.georings.data.MyLocation;
import my.georings.data.MyLocationCurrent;
import my.georings.dialog.ChooseLocationMapDialog;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class ChooseLocationItomizedOverlay extends ItemizedOverlay<OverlayItem> {

	
	private ArrayList<OverlayItem> overlays = new ArrayList<OverlayItem>();
	private ChooseLocationMapDialog context;
	private NewLocationOverlayItem newItem = null;
	
	// tylko jedna aktualna pozycja
	private LocationOverlayItem currentLocation = null;
	
	
	public ChooseLocationItomizedOverlay(Drawable defaultMarker, ChooseLocationMapDialog context) {
		super(boundCenterBottom(defaultMarker));
		this.context = context;
	}

	
	public void addLocationItem(MyLocation location){
		LocationOverlayItem item = new LocationOverlayItem(location);
		
		if(location instanceof MyLocationCurrent){
			if(currentLocation != null)
				overlays.remove(currentLocation);
			else{
				newItem = new NewLocationOverlayItem(location.getPoint());
				overlays.add(newItem);
			}
				
			currentLocation = item;
		}
		
		overlays.add(item);
		populate();
	}
	

	public void clear(){
		overlays.clear();
	}
	
	
	@Override
	protected OverlayItem createItem(int i) {
		return overlays.get(i);
	}

	@Override
	public int size() {
		return overlays.size();
	}
	
	@Override
	public boolean onTap(GeoPoint p, MapView mapView){
		if(((GeoPhoneRingsApp)context.getApplication()).getMyLocationsManager().isNewPointValid(p))
			setNewLocationPoint(p);
		else{
			Toast.makeText(context, "You cannot make two locations so close to each other", Toast.LENGTH_SHORT)
				.show();
		}
		return true;
	}
	
	
	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow){
		
		Paint on = new Paint();
		on.setARGB(50, 0, 100, 20);
		on.setStrokeWidth(0.2f);
		
		Paint off = new Paint();
		off.setARGB(40, 40, 40, 20);
		off.setStrokeWidth(0.2f);
		
		Paint current = new Paint();
		current.setARGB(30, 0, 10, 30);
		current.setStrokeWidth(0.2f);
		
		Paint text = new Paint();
		text.setARGB(200, 20, 20, 20);
		text.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
		
		Paint whiteBox = new Paint();
		whiteBox.setARGB(200, 255, 255, 255);
		whiteBox.setAntiAlias(true);
		
		Paint blackBox = new Paint();
		blackBox.setStyle(Paint.Style.STROKE);
		blackBox.setARGB(170, 0, 0, 0);
		blackBox.setStrokeWidth(0.2f);
		
		// rysowanie obszarow dla lokalizacji
		for(int i = 0; i < overlays.size(); ++i){
			
			if(overlays.get(i) == newItem)
				continue;
			
			LocationOverlayItem location = (LocationOverlayItem) overlays.get(i);
			
			float radiusPixels = 0.0f;
			Point screenPts = new Point();
            mapView.getProjection().toPixels(location.getPoint(), screenPts);
			
			if(location.getLocation() instanceof MyLocationCurrent){
				radiusPixels = mapView.getProjection().metersToEquatorPixels(((MyLocationCurrent)location.getLocation()).getAccuracy());
				canvas.drawCircle(screenPts.x, screenPts.y, radiusPixels, current);
			}else{
				radiusPixels = mapView.getProjection().metersToEquatorPixels(location.getLocation().getRadius());
				if(location.getLocation().isON())
					canvas.drawCircle(screenPts.x, screenPts.y, radiusPixels, on);
				else
					canvas.drawCircle(screenPts.x, screenPts.y, radiusPixels, off);
			}
		}
		super.draw(canvas, mapView, shadow);
		
		for(int i = 0; i < overlays.size(); ++i){
			
			if(overlays.get(i) == newItem)
				continue;
			
			LocationOverlayItem location = (LocationOverlayItem) overlays.get(i);
			
			if(location.getLocation() instanceof MyLocationCurrent){
				continue;
			}
			
			Point screenPts = new Point();
            mapView.getProjection().toPixels(location.getPoint(), screenPts);
            
            String name = location.getLocation().getName();
            
            Rect rect = new Rect();
            text.getTextBounds(name, 0, name.length() > 30 ? 30 : name.length(), rect);
            int offsetX = screenPts.x - (rect.right/2);
            rect.offsetTo(offsetX, screenPts.y-32);
            
            canvas.drawRoundRect(new RectF(rect.left-7, rect.top-3, rect.right+7, rect.bottom+3), 
            		2.0f, 2.0f, whiteBox);
            canvas.drawRoundRect(new RectF(rect.left-7, rect.top-3, rect.right+7, rect.bottom+3), 
            		2.0f, 2.0f, blackBox);
            
			canvas.drawText(location.getLocation().getName(), offsetX, screenPts.y-22, text);
		}
	}
	
	
	public GeoPoint getNewLocationPoint() {
		return newItem.getPoint();
	}
	
	public void setNewLocationPoint(GeoPoint newPoint){
		
		if(newItem != null){
			overlays.remove(newItem);
		}
		newItem = new NewLocationOverlayItem(newPoint);
		overlays.add(newItem);
		populate();
	}
	
	
	private class NewLocationOverlayItem extends OverlayItem{
		
		public NewLocationOverlayItem(GeoPoint point) {
			super(point, "", "");
			setMarker(boundCenterBottom(context.getResources().getDrawable(R.drawable.pinnew)));
		}
	}
	
	
	private class LocationOverlayItem extends OverlayItem{

		public LocationOverlayItem(MyLocation location) {
			super(location.getPoint(), location.getName(), 
					new String(location.isChangeVolume() ? "Volume: " + location.getVolume() + "\n": "").concat(
					new String("Vibration: " + (location.isVibra() ? "on" : "off") + "\n")).concat(
					new String("Ring changed: " + (location.isChangeRing() ? "yes" : "no")))
					);
			this.location = location;
			
			if(location instanceof MyLocationCurrent)
				setMarker(boundCenterBottom(context.getResources().getDrawable(R.drawable.pincurrent)));
			else if(!location.isON()){
				setMarker(boundCenterBottom(context.getResources().getDrawable(R.drawable.pin_disable)));
			}
		}
				
		public MyLocation getLocation() {
			return location;
		}

		private MyLocation location;
	}
}
